"""
程序运行自封装库
作者：一个
版本：V1.0.0
日期：2024-11-19
"""
import os.path
import time
from typing import Any

from retrying import retry


def work_logger(path: str = 'logs', is_retry: bool = True) -> Any:
    """
    爬虫工作日志装饰器
    记录工作信息，重试任务
    :param is_retry: 是否需要重试操作
    :param path: 日志文件存放目录
    :return:
    """
    # 判断是否存在日志文件夹地址，不存在就创建
    if not os.path.isdir(path):
        os.mkdir(path)

    def get_old_func(old_func):
        """
        old_func就是原本的函数
        :param old_func: 原本的功能程序，要执行的操作
        :return:
        """

        def new_func(*args, **kwargs):
            """
            新的函数，定义额外的功能
            保存工作信息，重试
            :param args: 原本函数的参数
            :param kwargs: 原本函数的参数
            :return:
            """
            with open(rf'{path}/info.txt', 'a', encoding='utf-8') as f:
                # 2024-11-19 21:29:12 :<function test at 0x00000285925F8550>((),{})
                f.write('%s :%s(%s,%s)\n' % (
                    time.strftime('%Y-%m-%d %H:%M:%S'),
                    old_func,
                    args,
                    kwargs
                ))

            try:
                res = old_func(*args, **kwargs)  # 调用原本的函数传入原本的参数，原封不动的执行原本的功能，保存函数执行的结果
            except TimeoutError as e:
                # 我们认为你是网络延迟等可以通过重试来补救的错误
                if is_retry:
                    # 判断你是否需要重试
                    # 2024-11-19 21:29:12 :<function test at 0x00000285925F8550>((),{})
                    @retry(stop_max_attempt_number=3, wait_random_min=1000, wait_random_max=3000)
                    def time_retry():
                        # 会对函数里面的内容进行检测，如果发送异常，则重新调用
                        with open(rf'{path}/retry.txt', 'a', encoding='utf-8') as f:
                            f.write('%s :%s(%s,%s) retry info:[%s]\n' % (
                                time.strftime('%Y-%m-%d %H:%M:%S'),
                                old_func,
                                args,
                                kwargs,
                                e
                            ))
                        return old_func(*args, **kwargs)  # 执行原本的函数

                    return time_retry()  # 出现超时异常，调用重试方法
                else:
                    # 不要重试，跳过，开始尝试下一个数据的获取
                    with open(rf'{path}/pass.txt', 'w', encoding='utf-8') as f:
                        f.write('%s|%s\n' % (args, kwargs))
            except Exception as e:
                with open(rf'{path}/error.txt', 'a', encoding='utf-8') as f:
                    # 2024-11-19 21:29:12 :<function test at 0x00000285925F8550>((),{})
                    f.write('%s :%s(%s,%s) error info:[%s]\n' % (
                        time.strftime('%Y-%m-%d %H:%M:%S'),
                        old_func,
                        args,
                        kwargs,
                        e
                    ))
            else:
                with open(rf'{path}/success.txt', 'a', encoding='utf-8') as f:
                    # 2024-11-19 21:29:12 :<function test at 0x00000285925F8550>((),{})
                    f.write('%s :%s(%s,%s) res:[%s]\n' % (
                        time.strftime('%Y-%m-%d %H:%M:%S'),
                        old_func,
                        args,
                        kwargs,
                        res
                    ))
                return res  # 返回原本函数执行的结果

        return new_func

    return get_old_func